#!/usr/bin/perl 

package ProcessManager;
use strict;
use Switch;
use Fifo;
use RoundRobin;

sub new {
    my $class = shift;
    my $self = {
    	_processor	 => shift,
        _processes	 => shift,
        _scheduler1  => undef,
        _output		 => undef,
    };
         
    bless $self, $class;
    return $self;
}

sub process {
	my( $self ) = @_;
	
	$self->{_scheduler1} = $self->_getScheduler();
		
	my $finished = 0;
	my $ticks = 0;
	
	while(!$finished){
		my @proc = _getProcess($self, $ticks);
		my $procLength = @proc;
		
		if($procLength){
			 $self->{_scheduler1}->putProcess(@proc);
			 splice $self->{_processes}, 0, $procLength;
		}
				
		$self->{_scheduler1}->tick();
				
		$finished = !$self->{_scheduler1}->isProcessing();
		
		$ticks += 1;
	}
}

sub setOutput{
	my( $self, $output ) = @_;
	$self->{_output}=$output;	
}

sub getProcesses{
	my( $self ) = @_;
	return $self->{_processes};
}

sub _getProcess{
	my( $self, $ticks ) = @_;
	my @ret;
	my @lst = @{$self->{_processes}};
	my $proc;
	foreach $proc (@lst){
		if($proc->{_startTime} eq $ticks){
			push @ret, $proc;
		}
	}
	return @ret;
}

sub _getScheduler{
	my( $self ) = @_;
	my $kernels = $self->{_processor}->getKernels();
	my $ThreadAlgorithm = $self->{_processor}->getThreadAlgorithm();
	my $ThreadQuantum = $self->{_processor}->getThreadQuantum();
	switch($self->{_processor}->getProcessAlgorithm()){
		case "FIFO" {return new Fifo($self->{_output}, $kernels, $ThreadAlgorithm, $ThreadQuantum);}
		case "RR" {return new RoundRobin($self->{_output}, $self->{_processor}->getQuantum(), $kernels, $ThreadAlgorithm, $ThreadQuantum);}
	}

}
1;
